package com.yourcompany.service.strategy;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yourcompany.api.dto.WxLoginDTO;
import com.yourcompany.api.entity.User;
import com.yourcompany.api.entity.UserOauth;
import com.yourcompany.api.enums.LoginTypeEnum;
import com.yourcompany.api.enums.OauthTypeEnum;
import com.yourcompany.api.service.UserOauthService;
import com.yourcompany.api.service.UserService;
import com.yourcompany.api.strategy.LoginStrategy;
import com.yourcompany.api.vo.LoginVO;
import com.yourcompany.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
public class WxQrLoginStrategy implements LoginStrategy {
    
    @Autowired
    private WxMpService wxMpService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private UserOauthService userOauthService;
    
    @Override
    public String getLoginType() {
        return LoginTypeEnum.WX_QR.getCode();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginVO login(WxLoginDTO loginDTO) {
        try {
            // 获取access_token
            WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(loginDTO.getCode());
            
            // 获取用户信息
            WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(accessToken, "zh_CN");
            
            // 查询授权信息
            LambdaQueryWrapper<UserOauth> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserOauth::getOauthType, OauthTypeEnum.WEIXIN.getCode())
                    .eq(UserOauth::getOauthId, userInfo.getOpenid());
            UserOauth oauth = userOauthService.getOne(wrapper);
            
            boolean isNewUser = false;
            if (oauth == null) {
                // 创建系统用户
                User user = new User();
                user.setUsername("wx_" + userInfo.getOpenid());
                user.setNickname(userInfo.getNickname());
                user.setAvatar(userInfo.getHeadImgUrl());
                user.setGender(userInfo.getSex());
                userService.save(user);
                
                // 创建授权信息
                oauth = new UserOauth();
                oauth.setUserId(user.getId());
                oauth.setOauthType(OauthTypeEnum.WEIXIN.getCode());
                oauth.setOauthId(userInfo.getOpenid());
                oauth.setUnionId(userInfo.getUnionId());
                oauth.setCredential(accessToken.getAccessToken());
                oauth.setExpiresIn(accessToken.getExpiresIn());
                oauth.setScope(accessToken.getScope());
                oauth.setRefreshToken(accessToken.getRefreshToken());
                oauth.setStatus(true);
                userOauthService.save(oauth);
                
                isNewUser = true;
            } else {
                // 更新access_token
                oauth.setCredential(accessToken.getAccessToken());
                oauth.setExpiresIn(accessToken.getExpiresIn());
                oauth.setScope(accessToken.getScope());
                oauth.setRefreshToken(accessToken.getRefreshToken());
                userOauthService.updateById(oauth);
            }
            
            // 生成token
            StpUtil.login(oauth.getUserId());
            String token = StpUtil.getTokenValue();
            
            // 获取用户信息
            User user = userService.getById(oauth.getUserId());
            
            // 返回登录结果
            LoginVO vo = new LoginVO();
            vo.setToken(token);
            vo.setUserId(user.getId());
            vo.setNickname(user.getNickname());
            vo.setAvatar(user.getAvatar());
            vo.setIsNewUser(isNewUser);
            return vo;
        } catch (WxErrorException e) {
            log.error("微信扫码登录失败", e);
            throw new BusinessException("登录失败");
        }
    }
} 